// File Name: rs485_logic.c
// Author: kukukukuku~
// Date: 2024-07-16

#include "./User/ADC/inc/adc_ctrl.h"
#include "./User/Flash/inc/flash_ctrl.h"
#include "./User/Key/inc/key_ctrl.h"
#include "./User/LED/inc/led_logic.h"
#include "./User/OLED/inc/oled_ctrl.h"
#include "./User/RS485/inc/rs485_logic.h"
#include "./User/Step_Motor/inc/step_motor_logic.h"
#include "./User/Sys/inc/init.h"
#include "./User/WS2812B/inc/ws2812b_ctrl.h"
#include "string.h"

/**
 * @brief   CRC16-Modbus算法
 * @param   data:       数据源
 * @param   dataLen:    数据个数
 * @retval  计算结果
 * @note    None
*/
uint16_t crc16_modbus_calc(uint8_t *data, uint16_t dataLen)
{
    uint16_t crcInit = 0xFFFF;
    uint16_t crcPoly = 0xA001;
    uint16_t crcVal = crcInit;
    
    for(uint16_t i = 0; i < dataLen; i++)
    {
        crcVal ^= data[i];
        for(uint8_t j = 0; j < 8; j++)
        {
            if(crcVal & 0x0001)
            {
                crcVal = (crcVal>>1) ^ crcPoly;
            }
            else
            {
                crcVal >>= 1;
            }
        }
    }
    
    return crcVal;
}


/**
 * @brief   RS485发送数据
 * @param   data:       数据源
 * @param   dataLen:    数据个数
 * @retval  None
 * @note    None
*/
void rs485_send_data(const uint8_t *data, uint8_t dataLen)
{
    if(dataLen == 0 || dataLen > RS485_USART_TX_BUFFER_LEN)
    {
        return;
    }
    
    usart_transmitter_enable(RS485_USART, TRUE);
    usart_receiver_enable(RS485_USART, FALSE);
    
    RS485_MODE_TX;
    
    while(dataLen--)
    {
        while(!usart_flag_get(RS485_USART, USART_TDC_FLAG));
        usart_data_transmit(RS485_USART, *data++);
    }
    while(!usart_flag_get(RS485_USART, USART_TDC_FLAG));
    
    RS485_MODE_RX;
    
    usart_transmitter_enable(RS485_USART, FALSE);
    usart_receiver_enable(RS485_USART, TRUE);
}


/**
 * @brief   RS485数据处理
 * @param   None
 * @retval  None
 * @note    None
*/
void rs485_data_handle(void)
{
    uint16_t crc16 = 0;
    
    if(rs485UsartRxFinishFlag)
    {
        //数据长度合理
        if(rs485UsartRxIndex >= 8)
        {
            //计算CRC
            crc16 = crc16_modbus_calc(rs485UsartRxBuffer, rs485UsartRxIndex - 2);
            
            //检验通过
            if(crc16 == (rs485UsartRxBuffer[rs485UsartRxIndex - 2] << 8 | rs485UsartRxBuffer[rs485UsartRxIndex - 1]) &&\
               rs485UsartRxBuffer[0] == rs485Id)
            {
                switch(rs485UsartRxBuffer[1])
                {
                    //读单个寄存器
                    case RS485_MODBUS_READ_SINGLE_REG_CODE:
                        if((rs485UsartRxBuffer[2] << 8 | rs485UsartRxBuffer[3]) == (uint16_t)(~(rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5])))
                        {
                            switch(rs485UsartRxBuffer[2] << 8 | rs485UsartRxBuffer[3])
                            {
                                case RS485_REG_MODBUS_ACTIVE_INTERVAL:
                                    rs485_modbus_read_single_reg_response(RS485_REG_MODBUS_ACTIVE_INTERVAL, rs485ActiveInterval);
                                    break;
                                case RS485_REG_KEY_CLICK_BEEP:
                                    rs485_modbus_read_single_reg_response(RS485_REG_KEY_CLICK_BEEP, keyClickBeep);
                                    break;
                                case RS485_REG_KEY_LONG_BEEP:
                                    rs485_modbus_read_single_reg_response(RS485_REG_KEY_LONG_BEEP, keyLongBeep);
                                    break;
                                
                                case RS485_REG_LED1_MODE:
                                    rs485_modbus_read_single_reg_response(RS485_REG_LED1_MODE, led1.mode);
                                    break;
                                case RS485_REG_LED2_MODE:
                                    rs485_modbus_read_single_reg_response(RS485_REG_LED2_MODE, led2.mode);
                                    break;
                                case RS485_REG_LED1_BREATH_STEP:
                                    rs485_modbus_read_single_reg_response(RS485_REG_LED1_BREATH_STEP, led1.breathStep);
                                    break;
                                case RS485_REG_LED2_BREATH_STEP:
                                    rs485_modbus_read_single_reg_response(RS485_REG_LED2_BREATH_STEP, led2.breathStep);
                                    break;
                                case RS485_REG_LED1_BLINK_FREQ:
                                    rs485_modbus_read_single_reg_response(RS485_REG_LED1_BLINK_FREQ, led1.blinkNum);
                                    break;
                                case RS485_REG_LED2_BLINK_FREQ:
                                    rs485_modbus_read_single_reg_response(RS485_REG_LED2_BLINK_FREQ, led2.blinkNum);
                                    break;
                                case RS485_REG_LED1_SWITCH:
                                    rs485_modbus_read_single_reg_response(RS485_REG_LED1_SWITCH, led1.state);
                                    break;
                                case RS485_REG_LED2_SWITCH:
                                    rs485_modbus_read_single_reg_response(RS485_REG_LED2_SWITCH, led2.state);
                                    break;
                                
                                case RS485_REG_OLED_DIR:
                                    rs485_modbus_read_single_reg_response(RS485_REG_OLED_DIR, oledDir);
                                    break;
                                case RS485_REG_OLED_LIGHT:
                                    rs485_modbus_read_single_reg_response(RS485_REG_OLED_LIGHT, oledLightLevel);
                                    break;
                                case RS485_REG_OLED_CURSOR:
                                    rs485_modbus_read_single_reg_response(RS485_REG_OLED_CURSOR, oledCursorStyle);
                                    break;
                                case RS485_REG_OLED_REFRESH_MS:
                                    rs485_modbus_read_single_reg_response(RS485_REG_OLED_REFRESH_MS, oledMainPageRefreshInterval);
                                    break;
                                case RS485_REG_OLED_MENU_NUMBER:
                                    rs485_modbus_read_single_reg_response(RS485_REG_OLED_MENU_NUMBER, oledMenuNumberFlag);
                                    break;
                                
                                case RS485_REG_STEP_MOTOR_STATE:
                                    rs485_modbus_read_single_reg_response(RS485_REG_STEP_MOTOR_STATE, stepMotorState);
                                    break;
                                case RS485_REG_STEP_MOTOR_MODE:
                                    rs485_modbus_read_single_reg_response(RS485_REG_STEP_MOTOR_MODE, stepMotorMode);
                                    break;
                                case RS485_REG_STEP_MOTOR_SPD:
                                    rs485_modbus_read_single_reg_response(RS485_REG_STEP_MOTOR_SPD, stepMotorSpd);
                                    break;
                                
                                case RS485_REG_WS2812B_MODE:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_MODE, ws2812bMode);
                                    break;
                                case RS485_REG_WS2812B_STOP_R:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_STOP_R, ws2812bStopRed);
                                    break;
                                case RS485_REG_WS2812B_STOP_G:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_STOP_G, ws2812bStopGreen);
                                    break;
                                case RS485_REG_WS2812B_STOP_B:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_STOP_B, ws2812bStopBlue);
                                    break;
                                case RS485_REG_WS2812B_CW_MODE:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CW_MODE, ws2812bCwMode);
                                    break;
                                case RS485_REG_WS2812B_CW_R:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CW_R, ws2812bCwRed);
                                    break;
                                case RS485_REG_WS2812B_CW_G:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CW_G, ws2812bCwGreen);
                                    break;
                                case RS485_REG_WS2812B_CW_B:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CW_B, ws2812bCwBlue);
                                    break;
                                case RS485_REG_WS2812B_CCW_MODE:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CCW_MODE, ws2812bCcwMode);
                                    break;
                                case RS485_REG_WS2812B_CCW_R:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CCW_R, ws2812bCcwRed);
                                    break;
                                case RS485_REG_WS2812B_CCW_G:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CCW_G, ws2812bCcwGreen);
                                    break;
                                case RS485_REG_WS2812B_CCW_B:
                                    rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CCW_B, ws2812bCcwBlue);
                                    break;
                                
                                case RS485_REG_TEMPERATURE:
                                    rs485_modbus_read_single_reg_response(RS485_REG_TEMPERATURE, (uint16_t)((uint32_t)temperature) << 8 | ((uint32_t)(temperature * 100) % 100));
                                    break;
                                case RS485_REG_V_REF:
                                    rs485_modbus_read_single_reg_response(RS485_REG_V_REF, (uint16_t)((uint32_t)vRef) << 8 | ((uint32_t)(vRef * 100) % 100));
                                    break;
                                case RS485_REG_VERSION_H:
                                    rs485_modbus_read_single_reg_response(RS485_REG_VERSION_H, VERSION_MAIN);
                                    break;
                                case RS485_REG_VERSION_L:
                                    rs485_modbus_read_single_reg_response(RS485_REG_VERSION_L, VERSION_SECOND << 8 | VERSION_PHASE);
                                    break;
                                default:
                                    break;
                            }
                        }
                        break;
                    //写单个寄存器
                    case RS485_MODBUS_WRITE_SINGLE_REG_CODE:
                        switch(rs485UsartRxBuffer[2] << 8 | rs485UsartRxBuffer[3])
                        {
                            case RS485_REG_SAVE:
                                if((rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5]) == 0)
                                {
                                    rs485SaveFlag = 1;
                                }
                                break;
                            case RS485_REG_REBOOT:
                                if((rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5]) == 0)
                                {
                                    rs485_modbus_write_single_reg_response(RS485_REG_REBOOT, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0);
                                    rs485RebootFlag = 1;
                                }
                                break;
                            case RS485_REG_RESET:
                                if((rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5]) == 0)
                                {
                                    rs485_modbus_write_single_reg_response(RS485_REG_RESET, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0);
                                    rs485ResetFlag = 1;
                                }
                                break;
                                
                            case RS485_REG_MODBUS_MODE:
                                rs485Mode = rs485_modbus_write_single_reg_response(RS485_REG_MODBUS_MODE, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 1);
                                break;
                            case RS485_REG_MODBUS_ID:
                                rs485Id = rs485_modbus_write_single_reg_response(RS485_REG_MODBUS_ID, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], RS485_ID_MIN, RS485_ID_MAX);
                                break;
                            case RS485_REG_MODBUS_BAUD_H:
                                rs485UsartBaudRateNew &= 0xFFFF;
                                rs485UsartBaudRateNew |= rs485_modbus_write_single_reg_response(RS485_REG_MODBUS_BAUD_H, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0xFFFF) << 16;
                                break;
                            case RS485_REG_MODBUS_BAUD_L:
                                rs485UsartBaudRateNew &= 0xFFFF0000;
                                rs485UsartBaudRateNew |= rs485_modbus_write_single_reg_response(RS485_REG_MODBUS_BAUD_L, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0xFFFF);
                                break;
                            case RS485_REG_MODBUS_ACTIVE_INTERVAL:
                                rs485ActiveInterval = rs485_modbus_write_single_reg_response(RS485_REG_MODBUS_ACTIVE_INTERVAL, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], RS485_ACTIVE_INTERVAL_MIN, RS485_ACTIVE_INTERVAL_MAX);
                                break;
                            
                            case RS485_REG_KEY_CLICK_BEEP:
                                keyClickBeep = rs485_modbus_write_single_reg_response(RS485_REG_KEY_CLICK_BEEP, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], KEY_CLICK_BEEP_MIN, KEY_CLICK_BEEP_MAX);
                                break;
                            case RS485_REG_KEY_LONG_BEEP:
                                keyLongBeep = rs485_modbus_write_single_reg_response(RS485_REG_KEY_LONG_BEEP, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], KEY_LONG_BEEP_MIN, KEY_LONG_BEEP_MAX);
                                break;
                            
                            case RS485_REG_LED1_MODE:
                                led1.mode = rs485_modbus_write_single_reg_response(RS485_REG_LED1_MODE, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 2);
                                led_set_mode(&led1, led1.mode);
                                break;
                            case RS485_REG_LED2_MODE:
                                led2.mode = rs485_modbus_write_single_reg_response(RS485_REG_LED2_MODE, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 2);
                                led_set_mode(&led2, led2.mode);
                                break;
                            case RS485_REG_LED1_BREATH_STEP:
                                led1.breathStep = rs485_modbus_write_single_reg_response(RS485_REG_LED1_BREATH_STEP, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], LED_BREATH_STEP_MIN, LED_BREATH_STEP_MAX);
                                led_set_breath_step(&led1, led1.breathStep);
                                break;
                            case RS485_REG_LED2_BREATH_STEP:
                                led2.breathStep = rs485_modbus_write_single_reg_response(RS485_REG_LED2_BREATH_STEP, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], LED_BREATH_STEP_MIN, LED_BREATH_STEP_MAX);
                                led_set_breath_step(&led2, led2.breathStep);
                                break;
                            case RS485_REG_LED1_BLINK_FREQ:
                                led1.blinkNum = rs485_modbus_write_single_reg_response(RS485_REG_LED1_BLINK_FREQ, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], LED_BLINK_TIME_MIN, LED_BLINK_TIME_MAX);
                                led_set_blink_time(&led1, led1.blinkNum);
                                break;
                            case RS485_REG_LED2_BLINK_FREQ:
                                led2.blinkNum = rs485_modbus_write_single_reg_response(RS485_REG_LED2_BLINK_FREQ, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], LED_BLINK_TIME_MIN, LED_BLINK_TIME_MAX);
                                led_set_blink_time(&led2, led2.blinkNum);
                                break;
                            case RS485_REG_LED1_SWITCH:
                                led1Switch = rs485_modbus_write_single_reg_response(RS485_REG_LED1_SWITCH, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 1);
                                break;
                            case RS485_REG_LED2_SWITCH:
                                led2Switch = rs485_modbus_write_single_reg_response(RS485_REG_LED2_SWITCH, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 1);
                                break;
                            
                            case RS485_REG_OLED_DIR:
                                oledDir = rs485_modbus_write_single_reg_response(RS485_REG_OLED_DIR, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 1);
                                if(oledDir == 0)
                                {
                                    oled_iic_send_data(0xC8, OLED_SEND_CMD);
                                    oled_iic_send_data(0xA1, OLED_SEND_CMD);
                                }
                                else
                                {
                                    oled_iic_send_data(0xC0, OLED_SEND_CMD);
                                    oled_iic_send_data(0xA0, OLED_SEND_CMD);
                                }
                                break;
                            case RS485_REG_OLED_LIGHT:
                                oledLightLevel = rs485_modbus_write_single_reg_response(RS485_REG_OLED_LIGHT, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 2);
                                if(oledLightLevel == 0)
                                {
                                    oled_iic_send_data(0x81, OLED_SEND_CMD);
                                    oled_iic_send_data(0xFA, OLED_SEND_CMD);
                                }
                                else if(oledLightLevel == 1)
                                {
                                    oled_iic_send_data(0x81, OLED_SEND_CMD);
                                    oled_iic_send_data(0x96, OLED_SEND_CMD);
                                }
                                else if(oledLightLevel == 2)
                                {
                                    oled_iic_send_data(0x81, OLED_SEND_CMD);
                                    oled_iic_send_data(0x32, OLED_SEND_CMD);
                                }
                                break;
                            case RS485_REG_OLED_CURSOR:
                                oledCursorStyle = rs485_modbus_write_single_reg_response(RS485_REG_OLED_CURSOR, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 6);
                                break;
                            case RS485_REG_OLED_REFRESH_MS:
                                oledMainPageRefreshInterval = rs485_modbus_write_single_reg_response(RS485_REG_OLED_REFRESH_MS, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5],\
                                OLED_MAIN_PAGE_REFRESH_INTERVAL_MIN, OLED_MAIN_PAGE_REFRESH_INTERVAL_MAX);
                                break;
                            case RS485_REG_OLED_MENU_NUMBER:
                                oledMenuNumberFlag = rs485_modbus_write_single_reg_response(RS485_REG_OLED_MENU_NUMBER, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 1);
                                break;
                            
                            case RS485_REG_STEP_MOTOR_MODE:
                                stepMotorMode = (StepMotorMode)rs485_modbus_write_single_reg_response(RS485_REG_STEP_MOTOR_MODE, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 4);
                                step_motor_set_mode(stepMotorMode);
                                break;
                            case RS485_REG_STEP_MOTOR_SPD:
                                stepMotorSpd = rs485_modbus_write_single_reg_response(RS485_REG_STEP_MOTOR_SPD, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 4);
                                step_motor_set_rotate_speed(stepMotorSpd);
                                break;
                            
                            case RS485_REG_WS2812B_MODE:
                                ws2812bMode = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_MODE, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 1);
                            case RS485_REG_WS2812B_STOP_R:
                                ws2812bStopRed = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_STOP_R, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0xFF);
                                break;
                            case RS485_REG_WS2812B_STOP_G:
                                ws2812bStopGreen = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_STOP_G, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0xFF);
                                break;
                            case RS485_REG_WS2812B_STOP_B:
                                ws2812bStopBlue = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_STOP_B, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0xFF);
                                break;
                            case RS485_REG_WS2812B_CW_MODE:
                                ws2812bCwMode = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_CW_MODE, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 1);
                                break;
                            case RS485_REG_WS2812B_CW_R:
                                ws2812bCwRed = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_CW_R, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0xFF);
                                break;
                            case RS485_REG_WS2812B_CW_G:
                                ws2812bCwGreen = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_CW_G, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0xFF);
                                break;
                            case RS485_REG_WS2812B_CW_B:
                                ws2812bCwBlue = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_CW_B, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0xFF);
                                break;
                            case RS485_REG_WS2812B_CCW_MODE:
                                ws2812bCcwMode = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_CCW_MODE, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 1);
                                break;
                            case RS485_REG_WS2812B_CCW_R:
                                ws2812bCcwRed = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_CCW_R, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0xFF);
                                break;
                            case RS485_REG_WS2812B_CCW_G:
                                ws2812bCcwGreen = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_CCW_G, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0xFF);
                                break;
                            case RS485_REG_WS2812B_CCW_B:
                                ws2812bCcwBlue = rs485_modbus_write_single_reg_response(RS485_REG_WS2812B_CCW_B, rs485UsartRxBuffer[4] << 8 | rs485UsartRxBuffer[5], 0, 0xFF);
                                break;
                            default:
                                break;
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        
        memset(rs485UsartRxBuffer, 0, sizeof(rs485UsartRxBuffer));
        rs485UsartRxIndex = 0;
        rs485UsartRxFinishFlag = 0;
    }
}


/**
 * @brief   RS485 Modbus读单个寄存器响应
 * @param   regAddr:    寄存器地址
 * @param   regData:    寄存器数据
 * @retval  None
 * @note    None
*/
void rs485_modbus_read_single_reg_response(uint16_t regAddr, uint16_t regData)
{
    uint8_t i = 0;
    uint16_t crc16 = 0;
    
    memset(rs485UsartTxBuffer, 0, sizeof(rs485UsartTxBuffer));
    
    rs485UsartTxBuffer[i++] = rs485Id;
    rs485UsartTxBuffer[i++] = RS485_MODBUS_READ_SINGLE_REG_CODE;
    rs485UsartTxBuffer[i++] = regAddr >> 8 & 0xFF;
    rs485UsartTxBuffer[i++] = regAddr & 0xFF;
    rs485UsartTxBuffer[i++] = regData >> 8 & 0xFF;
    rs485UsartTxBuffer[i++] = regData & 0xFF;
    crc16 = crc16_modbus_calc(rs485UsartTxBuffer, i);
    rs485UsartTxBuffer[i++] = crc16 >> 8 & 0xFF;
    rs485UsartTxBuffer[i++] = crc16 & 0xFF;
    
    rs485_send_data(rs485UsartTxBuffer, i);
}


/**
 * @brief   RS485 Modbus写单个寄存器响应
 * @param   regAddr:    寄存器地址
 * @param   data:       接收到的数据
 * @param   regDataMin: 寄存器数据最小值
 * @param   regDataMax: 寄存器数据最大值
 * @retval  寄存器数据
 * @note    None
*/
uint16_t rs485_modbus_write_single_reg_response(uint16_t regAddr, uint16_t data, uint16_t regDataMin, uint16_t regDataMax)
{
    uint8_t i = 0;
    uint16_t crc16 = 0;
    
    if(data < regDataMin)
    {
        data = regDataMin;
    }
    else if(data > regDataMax)
    {
        data = regDataMax;
    }
    
    memset(rs485UsartTxBuffer, 0, sizeof(rs485UsartTxBuffer));
    
    rs485UsartTxBuffer[i++] = rs485Id;
    rs485UsartTxBuffer[i++] = RS485_MODBUS_WRITE_SINGLE_REG_CODE;
    rs485UsartTxBuffer[i++] = regAddr >> 8 & 0xFF;
    rs485UsartTxBuffer[i++] = regAddr & 0xFF;
    rs485UsartTxBuffer[i++] = data >> 8 & 0xFF;
    rs485UsartTxBuffer[i++] = data & 0xFF;
    crc16 = crc16_modbus_calc(rs485UsartTxBuffer, i);
    rs485UsartTxBuffer[i++] = crc16 >> 8 & 0xFF;
    rs485UsartTxBuffer[i++] = crc16 & 0xFF;
    
    rs485_send_data(rs485UsartTxBuffer, i);
    
    return data;
}
